import { _decorator, Component, director, Event, EventTouch, Node, Prefab, randomRangeInt, Sprite, SpriteFrame, Tween, tween, UIOpacity, UITransform, v3, Vec2, Vec3 } from 'cc';
import { CharacterWearType, GameData } from './GameData';
import { Character } from './Character';
import { WearItem } from './WearItem';
import { PoolManager } from '../../Scripts/Framework/Managers/PoolManager';
import { Panel, UIManager } from '../../Scripts/Framework/Managers/UIManager';
import { ProjectEventManager, ProjectEvent } from '../../Scripts/Framework/Managers/ProjectEventManager';
const { ccclass, property } = _decorator;

@ccclass('ChangeManager')
export class ChangeManager extends Component {

    private static instance: ChangeManager;
    public static get Instance(): ChangeManager {
        return this.instance;
    }

    static lastScene: string;

    static GoChangeScene() {
        this.lastScene = director.getScene().name;
        UIManager.ShowPanel(Panel.LoadingPanel, "ChangeScene");
    }

    protected onLoad(): void {
        ChangeManager.instance = this;
    }

    @property(Node)
    light: Node;

    @property(Node)
    characters: Node;

    @property(Node)
    fadePanel: Node;

    @property(Node)
    top: Node;

    @property(Node)
    items: Node;

    @property(Node)
    colors: Node;

    @property(Node)
    gou: Node;

    @property(Node)
    circle: Node;

    @property(Node)
    backColor: Node;

    @property(Node)
    buttons: Node;

    @property(Node)
    tutorial: Node;

    @property(Node)
    hand: Node;

    @property(SpriteFrame)
    emptySf: SpriteFrame;

    @property(SpriteFrame)
    normalSf: SpriteFrame;

    @property(SpriteFrame)
    clickSf: SpriteFrame;

    @property(Character)
    character: Character;

    @property([Node])
    panels: Node[] = [];

    choose = 0;
    topNum = 0;
    subNum = 0;
    isEmpty = false;
    isMale = false;
    checkFemale = false;
    wearTypes = [[6, 4, 5], [0, 0], [2, 2, 3, 15], [1, 9, 10], [13, 14, 8, 7, 11, 12]]

    start() {
        this.CharacterInit();
        this.ChangeLight();
        this.InitTutorial();
        ProjectEventManager.emit(ProjectEvent.弹出窗口);
    }

    update(deltaTime: number) {

    }

    InitTutorial() {
        this.tutorial.active = GameData.Instance.getNumberData("Tutorial") == 0;
    }

    NextTutorial() {
        if (GameData.tutorial == 4) {
            GameData.tutorial++;
            this.tutorial.active = false;
            return;
        }
        this.tutorial.children[0].children[GameData.tutorial].active = false;
        this.scheduleOnce(() => {
            GameData.tutorial++;
            this.tutorial.children[0].children[GameData.tutorial].active = true;
            this.hand.setPosition(this.tutorial.children[0].children[GameData.tutorial].getPosition());
        }, 1);
    }

    CharacterInit() {
        let data = GameData.Instance.getRecordData("PersonData");
        for (let i = 0; i < data.length; i++) {
            const element = data[i];
            let character = this.characters.children[i].children[1]?.getComponent(Character);
            if (!character) character = Character.Init(this.characters.children[i]);
            character.Init(element);
        }
        this.light.setSiblingIndex(2);
    }

    ChangeLight() {
        // let pos = this.characters.children[this.choose].getWorldPosition().subtract3f(0, 45 * 0.55, 0);
        // this.light.setWorldPosition(pos);
        this.light.setParent(this.characters.children[this.choose]);
        this.light.setPosition(v3(0, -50));
    }

    Choose(event: Event) {
        let target: Node = event.target;
        let num = target.getSiblingIndex();
        if (this.tutorial.active) {
            if (num != 0) return;
            else this.NextTutorial();
        }
        if (this.choose != num) {
            this.choose = num;
            this.ChangeLight();
        }
        else this.Fade();
    }

    Fade() {
        let num = this.panels[0].active ? 0 : 1;
        if (this.tutorial.active && num == 1) return;
        this.fadePanel.active = true;
        tween(this.fadePanel.getComponent(UIOpacity))
            .to(1, { opacity: 255 })
            .call(() => {
                this.panels[num].active = false;
                this.panels[1 - num].active = true;
                if (num == 0) this.ClothesInit();
                else this.CharacterInit();
            })
            .to(0.5, { opacity: 0 })
            .call(() => {
                this.fadePanel.active = false;
            })
            .start();
    }

    ClothesInit() {
        let data = GameData.Instance.getRecordData("PersonData");
        this.character.Init(data[this.choose]);
        this.BackColor();
    }

    Reset() {
        if (this.tutorial.active) return;
        let data = GameData.defaultData.PersonData[this.choose];
        this.character.Init(data);
        let curData = GameData.Instance.getRecordData("PersonData");
        curData[this.choose].data = data.data;
        curData[this.choose].color = data.color;
        GameData.Instance.setRecordData("PersonData", curData);
    }

    Random() {
        if (this.tutorial.active) return;
        let content = this.colors.children[0].children[0];
        let color = content.children[randomRangeInt(0, content.children.length)].children[0].getComponent(Sprite).color;
        this.character.ColorInit(color);
        this.CheckGou();
        let data = GameData.Instance.getRecordData("PersonData");
        data[this.character.id].data.hair = randomRangeInt(-1, 15);
        data[this.character.id].data.headwear = randomRangeInt(-1, 16);
        data[this.character.id].data.up = randomRangeInt(-1, 16);
        data[this.character.id].data.bottom = randomRangeInt(-1, 8);
        data[this.character.id].data.eye = randomRangeInt(0, 8);
        data[this.character.id].data.mouth = randomRangeInt(0, 8);
        data[this.character.id].data.eyebrow = randomRangeInt(-1, 8);
        data[this.character.id].data.belt = randomRangeInt(-1, 7);
        data[this.character.id].data.cloak = randomRangeInt(-1, 6);
        data[this.character.id].data.Learwear = randomRangeInt(-1, 8);
        data[this.character.id].data.Rearwear = randomRangeInt(-1, 8);
        data[this.character.id].data.Lhandwear = randomRangeInt(-1, 7);
        data[this.character.id].data.Rhandwear = randomRangeInt(-1, 7);
        data[this.character.id].data.necklace = randomRangeInt(-1, 8);
        data[this.character.id].data.scarf = randomRangeInt(-1, 5);
        data[this.character.id].data.shoe = randomRangeInt(-1, 16);
        this.character.Init(data[this.character.id]);
        GameData.Instance.setRecordData("PersonData", data);
    }

    ChooseTop(event: Event) {
        if (this.tutorial.active) this.NextTutorial();
        let target: Node = event.target;
        let num = target.getSiblingIndex();
        if (this.topNum != num) {
            this.topNum = num;
            this.top.children[0].active = false;
            this.top.children[num].active = true;
            this.subNum = 0;
            if (this.topNum != 0) this.InitWear();
            else this.InitColor();
            this.circle.setWorldPosition(this.top.children[this.topNum].children[0].getWorldPosition());
        }
    }

    ChooseSub(event: Event) {
        if (this.tutorial.active) this.NextTutorial();
        let target: Node = event.target;
        let num = target.getSiblingIndex();
        if (this.subNum != num) {
            this.subNum = num;
            this.InitWear();
            this.circle.setWorldPosition(this.top.children[this.topNum].children[this.subNum].getWorldPosition());
        }
    }

    CheckGou() {
        let color = this.character.skins[0].color;
        for (let i = 0; i < this.colors.children[0].children[0].children.length; i++) {
            const element = this.colors.children[0].children[0].children[i];
            if (element.children[0].getComponent(Sprite).color.equals(color)) {
                this.gou.setParent(element);
                this.gou.setPosition(Vec3.ZERO);
                break;
            }
        }
    }

    InitColor() {
        this.colors.active = true;
        this.items.active = false;
        this.buttons.active = true;
        this.CheckGou();
    }

    InitWear() {
        this.backColor.active = true;
        this.colors.active = false;
        this.items.active = true;
        this.buttons.active = false;
        let num = this.wearTypes[this.topNum - 1][this.subNum];
        let data = GameData.Instance.getRecordData("PersonData")[this.character.id].data;
        let arr = [...(Object.values(data))];
        let curId = arr[num] as number;
        this.isEmpty = !(this.topNum == 1 && this.subNum > 0);
        let content = this.items.children[0].children[0];
        if (this.isEmpty) {
            let wearItem: WearItem;
            if (!content.children[0]) {
                let node: Node = PoolManager.GetNodeByPrefab(GameData.prefabsBundle.get("WearItem", Prefab), content);
                wearItem = node.getComponent(WearItem);
            }
            else {
                wearItem = content.children[0].getComponent(WearItem);
                content.children[0].active = true;
            }
            wearItem.sprite.spriteFrame = curId == -1 ? this.clickSf : this.normalSf;
            wearItem.childSprite.spriteFrame = this.emptySf;
        }
        this.checkFemale = (this.topNum - 1 == 1 || this.topNum - 1 == 2) && this.subNum == 0;
        this.isMale = (this.topNum - 1 == 1 || this.topNum - 1 == 2) && this.subNum == 1;
        let str = CharacterWearType[num];
        if (str.includes("L") || str.includes("R")) str = str.slice(1);
        let datas = GameData.itemBundle.getDirWithPath("Clothes/" + str, SpriteFrame);
        let length = content.children.length;
        for (let i = 0; i < datas.length; i++) {
            if (this.isMale && i < 10 || (this.checkFemale && !this.isMale && i > 9)) continue;
            let url = "Clothes/" + str + "/" + i + "/spriteFrame";
            let sf = GameData.itemBundle.get(url, SpriteFrame);
            if (!sf) continue;
            let element = content.children[i + (this.isEmpty ? 1 : 0) - (this.isMale ? 10 : 0)];
            let wearItem: WearItem;
            if (!element) {
                let node: Node = PoolManager.GetNodeByPrefab(GameData.prefabsBundle.get("WearItem", Prefab), content);
                wearItem = node.getComponent(WearItem);
            }
            else {
                wearItem = element.getComponent(WearItem);
                element.active = true;
            }
            wearItem.sprite.spriteFrame = curId == i ? this.clickSf : this.normalSf;
            wearItem.childSprite.spriteFrame = sf;
        }
        if (datas.length + (this.isEmpty ? 1 : 0) - (this.isMale || this.checkFemale ? 10 : 0) < length) {
            for (let i = datas.length + (this.isEmpty ? 1 : 0) - (this.isMale || this.checkFemale ? 10 : 0); i < content.children.length; i++) {
                const element = content.children[i];
                element.active = false;
            }
        }
    }

    BackColor() {
        this.circle.setWorldPosition(this.top.children[0].children[0].getWorldPosition());
        this.backColor.active = false;
        this.top.children[0].active = true;
        if (this.topNum > 0) this.top.children[this.topNum].active = false;
        this.topNum = 0;
        this.InitColor();
    }

    ChangeColor(event: Event) {
        if (this.tutorial.active) this.NextTutorial();
        let target: Node = event.target;
        let color = target.children[0].getComponent(Sprite).color;
        this.character.ColorInit(color);
        this.CheckGou();
    }

    ClothesClick(target: Node) {
        let num = target.getSiblingIndex() - (this.isEmpty ? 1 : 0) + (this.isMale ? 10 : 0);
        if (target.getSiblingIndex() == 0 && this.isEmpty) num = -1;
        let num2 = this.wearTypes[this.topNum - 1][this.subNum];
        let data = GameData.Instance.getRecordData("PersonData");
        switch (num2) {
            case 0:
                data[this.character.id].data.hair = num;
                break;
            case 1:
                data[this.character.id].data.headwear = num;
                break;
            case 2:
                data[this.character.id].data.up = num;
                break;
            case 3:
                data[this.character.id].data.bottom = num;
                break;
            case 4:
                data[this.character.id].data.eye = num;
                break;
            case 5:
                data[this.character.id].data.mouth = num;
                break;
            case 6:
                data[this.character.id].data.eyebrow = num;
                break;
            case 7:
                data[this.character.id].data.belt = num;
                break;
            case 8:
                data[this.character.id].data.cloak = num;
                break;
            case 9:
                data[this.character.id].data.Learwear = num;
                break;
            case 10:
                data[this.character.id].data.Rearwear = num;
                break;
            case 11:
                data[this.character.id].data.Lhandwear = num;
                break;
            case 12:
                data[this.character.id].data.Rhandwear = num;
                break;
            case 13:
                data[this.character.id].data.necklace = num;
                break;
            case 14:
                data[this.character.id].data.scarf = num;
                break;
            case 15:
                data[this.character.id].data.shoe = num;
                break;
        }
        GameData.Instance.setRecordData("PersonData", data);
        this.character.Init(data[this.character.id]);
        this.InitWear();
    }

    Back() {
        if (this.tutorial.active) return;
        UIManager.ShowPanel(Panel.LoadingPanel, ChangeManager.lastScene);
    }

}


